/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#ifndef __PQ_NetManager_H__
#define __PQ_NetManager_H__

#include "ClientPrerequisites.h"

#include "OgreTimer.h"
#include "TCPSocket.h"
#include "NetInputStream.h"
#include "NetOutputStream.h"

using namespace PQNet;

namespace PQClient
{
	/*This class is used to manage the whole network layer.
	*/
	class NetManager
	{
	public:
		enum ConnectState
		{
			Connect_State_Unkown,
			Connect_State_Connect_Success,
			Connect_State_Connect_Fail,
			Connect_State_Socket_Open_Fail,
			Connect_State_Time_Out,
		};

	protected:
		NetManager();
	public:
		static NetManager& getSingleton()
		{
			static NetManager inst;
			return inst;
		}

		void init();

		/*Get current running scene's state,and update the running scene.
		*/
		void update(float deltaT);
		
		void updateLoginScene(float deltaT);
		void updateGameWordScene(float deltaT);
		void updateCharacterSelectScene(float deltaT);
		void updateCharacterCreateScene(float deltaT);
		void updateServerChangeScene(float deltaT);
		void updateEnterWorldScene(float deltaT);


		/*Connect to the server.
		*/
		void connect(std::string addr,int32 port);
		/*
		*/
		//void send(Packet* packet);

		/*Disconnect the server.
		*/
		void close();

		//Connect to server successfully,and ready to enter game
		void gameEnterReady();
	protected:
		
		//WINDOWS network thread
		static UINT CALLBACK _connectThreadWin(LPVOID pParam);

		/*Connect to server thread implementation.
		*/
		int connectThreadWin();

		//React state Server_Change_Connecting.
		void waitConnecting();

		void waitPacket();

		void connectFail(ConnectState state);
		void connectSuccess();

	protected:
		bool _inited;
		HANDLE _connectThread;//connect thread handle

		TCPSocket _socket;
		NetInputStream _inputStream;//net input stream(buffer)
		NetOutputStream _outputStream;//net output stream(buffer)

		std::string _serverAddr;
		int32 _serverPort;

		ulong _timeBeginConnect;

		Ogre::Timer _timer;//network timer


	};
}
#endif
